Generalise `find_project` to not always search parents.
authorHuon Wilson <dbau.pp+github@gmail.com>
Sat, 28 Jun 2014 09:24:15 +0000 (19:24 +1000)
committerHuon Wilson <dbau.pp+github@gmail.com>
Sun, 29 Jun 2014 06:46:24 +0000 (16:46 +1000)
Also, add a helper around `find_project` that returns `dir/file` rather
than just `dir`.

src/bin/cargo-build.rs [changed mode: 0644->0755]
src/bin/cargo-test.rs [changed mode: 0644->0755]
src/bin/cargo.rs [changed mode: 0644->0755]
src/cargo/util/important_paths.rs

old mode 100644 (file)
new mode 100755 (executable)
index c3d3c96..f88cf54
@@ -16,7 +16,7 @@ use cargo::{execute_main_without_stdin};
 use cargo::ops;
 use cargo::core::MultiShell;
 use cargo::util::{CliResult, CliError};
-use cargo::util::important_paths::find_project;
+use cargo::util::important_paths::find_project_manifest;
 
 #[deriving(PartialEq,Clone,Decodable,Encodable)]
 pub struct Options {
@@ -37,8 +37,7 @@ fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
 
     let root = match options.manifest_path {
         Some(path) => Path::new(path),
-        None => try!(find_project(os::getcwd(), "Cargo.toml")
-                    .map(|path| path.join("Cargo.toml"))
+        None => try!(find_project_manifest(&os::getcwd(), "Cargo.toml")
                     .map_err(|_| {
                         CliError::new("Could not find Cargo.toml in this \
                                        directory or any parent directory",
old mode 100644 (file)
new mode 100755 (executable)
index 8849b2d..5adb711
@@ -16,7 +16,7 @@ use cargo::{execute_main_without_stdin};
 use cargo::core::{MultiShell};
 use cargo::util;
 use cargo::util::{CliResult, CliError};
-use cargo::util::important_paths::find_project;
+use cargo::util::important_paths::find_project_manifest;
 
 #[deriving(PartialEq,Clone,Decodable)]
 struct Options {
@@ -33,8 +33,7 @@ fn main() {
 fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
     let root = match options.manifest_path {
         Some(path) => Path::new(path),
-        None => try!(find_project(os::getcwd(), "Cargo.toml")
-                    .map(|path| path.join("Cargo.toml"))
+        None => try!(find_project_manifest(&os::getcwd(), "Cargo.toml")
                     .map_err(|_| {
                         CliError::new("Could not find Cargo.toml in this \
                                        directory or any parent directory",
old mode 100644 (file)
new mode 100755 (executable)
index 454e84e..ed3a12d
@@ -142,7 +142,7 @@ fn config_list(args: ConfigListFlags, _: &mut MultiShell) -> CliResult<Option<Co
 }
 
 fn locate_project(_: NoFlags, _: &mut MultiShell) -> CliResult<Option<ProjectLocation>> {
-    let root = try!(find_project(os::getcwd(), "Cargo.toml").map_err(|e| {
+    let root = try!(find_project(&os::getcwd(), "Cargo.toml").map_err(|e| {
         CliError::from_boxed(e, 1)
     }));
 
index 7bcc9a551b82b0bf0aafca5527099f2cbf8d69db..df7a6bd7a5edc9e17b16f1ed70fdaea0127341d1 100644 (file)
@@ -1,15 +1,42 @@
 use util::{CargoResult, human};
 
-pub fn find_project(pwd: Path, file: &str) -> CargoResult<Path> {
+/// Iteratively search for `file` in `pwd` and its parents, returning
+/// the path of the directory.
+pub fn find_project(pwd: &Path, file: &str) -> CargoResult<Path> {
+    find_project_manifest(pwd, file)
+        .map(|mut p| {
+            // remove the file, leaving just the directory
+            p.pop();
+            p
+        })
+}
+
+/// Iteratively search for `file` in `pwd` and its parents, returning
+/// the path to the file.
+pub fn find_project_manifest(pwd: &Path, file: &str) -> CargoResult<Path> {
     let mut current = pwd.clone();
 
     loop {
-        if current.join(file.clone()).exists() {
-            return Ok(current)
+        let manifest = current.join(file);
+        if manifest.exists() {
+            return Ok(manifest)
         }
 
         if !current.pop() { break; }
     }
 
-    Err(human(format!("no manifest found in `{}`", pwd.display())))
+    Err(human(format!("Could not find `{}` in `{}` or any parent directory",
+                      file, pwd.display())))
+}
+
+/// Return the path to the `file` in `pwd`, if it exists.
+pub fn find_project_manifest_exact(pwd: &Path, file: &str) -> CargoResult<Path> {
+    let manifest = pwd.join(file);
+
+    if manifest.exists() {
+        Ok(manifest)
+    } else {
+        Err(human(format!("Could not find `{}` in `{}`",
+                          file, pwd.display())))
+    }
 }